package cn.edu.sgu.www.pms.shiro;

import cn.edu.sgu.www.pms.consts.RedisKeyPrefixes;
import cn.edu.sgu.www.pms.entity.User;
import cn.edu.sgu.www.pms.exception.GlobalException;
import cn.edu.sgu.www.pms.mapper.ApplicationMapper;
import cn.edu.sgu.www.pms.mapper.PermissionMapper;
import cn.edu.sgu.www.pms.mapper.UserMapper;
import cn.edu.sgu.www.pms.restful.ResponseCode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.Set;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
public class UsernameRealm extends AuthorizingRealm {

    @Value("${spring.application.name}")
    private String service;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private ApplicationMapper applicationMapper;

    @Override
    public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 通过应用名查询应用ID
        Integer serviceId = applicationMapper.getServiceId(service);

        if (serviceId == null) {
            throw new GlobalException(ResponseCode.NOT_FOUND, "查询应用失败，应用" + service + "不存在！");
        }

        // 得到用户名
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        String username = usernamePasswordToken.getUsername();

        // 通过用户名和应用ID查询用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("username", username);
        queryWrapper.eq("service_id", serviceId);

        User user = userMapper.selectOne(queryWrapper);

        if (user == null) {
            throw new AuthenticationException("用户名或密码错误，登录失败");
        }

        return new SimpleAuthenticationInfo(user, user.getPassword(), username);
    }

    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        String username = user.getUsername();

        // 通过应用名查询应用ID
        Integer serviceId = applicationMapper.getServiceId(service);

        // 通过用户名查询用户的权限
        Set<String> permissions = permissionMapper.selectUserPermissions(username, serviceId);

        // 设置权限
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        authorizationInfo.setStringPermissions(permissions);

        return authorizationInfo;
    }

    /**
     * 配置授权缓存的key
     * @param principals PrincipalCollection
     * @return String
     */
    @Override
    public String getAuthorizationCacheKey(PrincipalCollection principals) {
        // 获取登录的用户信息
        User user = (User) principals.getPrimaryPrincipal();
        // 得到用户名
        String username = user.getUsername();

        return RedisKeyPrefixes.PREFIX_CACHE_AUTHORIZATION + username;
    }

}